﻿using System;
using System.Collections;
using System.Text.RegularExpressions;
using Tavis.Http;

namespace Tavis.Tools {

        public class QueryParameters {
            private Hashtable _Values = new Hashtable(StringComparer.InvariantCultureIgnoreCase);

            public QueryParameters(string queryString) {
                var reg = new Regex(@"(\w*)=([^&]*)&?");
                foreach (Match m in reg.Matches(queryString)) {

                    string key = m.Groups[1].Value.ToLowerInvariant();
                    
                    string value = m.Groups[2].Value;
                    if (value.StartsWith("{")) {
                        key = value.Substring(1, value.Length - 2);
                    } 
                    _Values[key] = HttpUtility.UrlDecode(value);
                    
                }
                
            }

            public bool Contains(string parameterName) {
                return _Values.ContainsKey(parameterName);
            }

            public int Count {
                get { return _Values.Count; }
            }

            public void AddValue(string parameterName, object value) {
                parameterName = parameterName.ToLowerInvariant();
                if (_Values.ContainsKey(parameterName)) {
                    RemoveValue(parameterName);
                }
                _Values.Add(parameterName, value);
            }

            public void RemoveValue(string parameterName) {
                parameterName = parameterName.ToLowerInvariant();
                if (_Values.ContainsKey(parameterName)) {
                    _Values.Remove(parameterName);
                }
            }

            public T GetValue<T>(string parameterName) {
                parameterName = parameterName.ToLowerInvariant();
                return GetValue(parameterName, default(T));
            }

            public T GetValue<T>(string parameterName, T defaultValue) {
                parameterName = parameterName.ToLowerInvariant();
                T value = defaultValue;
                if (_Values.ContainsKey(parameterName.ToLowerInvariant())) {
                    value = (T)ChangeType(_Values[parameterName.ToLowerInvariant()], typeof(T));
                }
                return value;
            }

            public void SetValue(string parameterName, string value) {
                parameterName = parameterName.ToLowerInvariant();
                if (_Values.ContainsKey(parameterName)) {
                    _Values[parameterName] = value;
                }
            }

            private static object ChangeType(object value, Type conversionType) {
                if (conversionType.IsGenericType &&
                    conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) {

                    if (value == null)
                        return null;

                    var nullableConverter = new System.ComponentModel.NullableConverter(conversionType);

                    conversionType = nullableConverter.UnderlyingType;
                }

                if (conversionType.FullName == "System.Int32" && (string)value == "") {
                    value = 0;
                }

                return Convert.ChangeType(value, conversionType);
            }

            public Hashtable GetParameterHashtable() {
                return _Values;
            }

            internal void RemoveAllParameters() {
                _Values.Clear();
            }
        }

}
